import { createElements, define, itag } from "../itag/index.js";
import type { IRequestFieldElement } from "./IFieldElement.js";
import type { StringRequestFieldOption } from "./RequestOption.js";
import * as styles from "./styles.js";

/**
 * StringGroupElement - 用于处理带有字节表示的字符串输入的自定义HTML元素
 * 显示字符串内容以及字节范围信息
 * 实现IGroupElement接口
 */
export class StringRequestFieldElement extends HTMLElement implements IRequestFieldElement {
    /** 起始字节位置 */
    #begin: number = 0;

    /** 组件内DOM元素的引用 */
    readonly #elms = createElements({
        input: "input",
        name: "div",
        range: "div",
    });

    #option: StringRequestFieldOption | null = null;

    /** 组件封装的Shadow Root */
    #sr: ShadowRoot;

    /** 宽度字段的字节长度 */
    #widthLength: number = 0;

    /**
     * 初始化组件结构和事件处理程序
     */
    constructor() {
        super();
        this.#sr = this.attachShadow({ mode: "open" });
        this.#sr.adoptedStyleSheets.push(styles.sheet);

        itag`
${this.#sr}
    ${this.#elms.input} .${styles.input} .${styles.string}
    ${this.#elms.name} .${styles.name}
    ${this.#elms.range} .${styles.range}
    `;

        // 输入变化时更新字节范围显示
        this.#elms.input.addEventListener("keyup", () => {
            this.#updateRange();
        });
    }

    /**
     * 返回字符串的字节表示，包含长度前缀
     * 将字符串转换为UTF-8字节数组，并在前面添加基于配置宽度长度的字符串长度
     *
     * @returns 表示字符串数据的字节数组
     */
    data(): number[] {
        const encoder = new TextEncoder();
        const buf = encoder.encode(this.#elms.input.value);
        const len = buf.length;
        const data = [];

        // 在指定的字节数(widthLength)中存储字符串长度
        for (let i = 0; i < this.#widthLength; i++) {
            data.push((len >> (i * 8)) & 0xff);
        }

        // 添加字符串字节
        data.push(...buf);
        return data;
    }

    /**
     * 计算此元素的总字节长度
     * 包括宽度字段和编码的字符串字节
     *
     * @returns 总字节长度
     */
    byteLength(): number {
        const encoder = new TextEncoder();
        const buf = encoder.encode(this.#elms.input.value);
        return this.#widthLength + buf.length;
    }

    get name(): string {
        return this.#option?.name ?? "";
    }

    get option(): StringRequestFieldOption | null {
        return this.#option;
    }
    set option(value: StringRequestFieldOption | null) {
        if (value === this.#option) {
            return;
        }
        this.#option = value;
        this.#elms.name.textContent = value?.name ?? "";
        this.#elms.input.value = value?.value ?? "";
        this.#widthLength = value?.length ?? 0;
        this.#updateRange();
    }

    /**
     * 设置起始字节位置并更新范围显示
     *
     * @param value 新的起始字节位置
     */
    setBegin(value: number): void {
        if (this.#begin === value) {
            return;
        }
        this.#begin = value;
        this.#updateRange();
    }

    /**
     * 更新显示的字节范围信息
     * 格式: [begin - (begin+widthLength)) [(begin+widthLength) - (begin+total length)]
     * 第一部分表示宽度字段，第二部分表示字符串数据
     */
    #updateRange() {
        this.#elms.range.textContent = `${this.#begin} - ${this.#begin + this.#widthLength} ) [ ${
            this.#begin + this.#widthLength
        } - ${this.#begin + this.byteLength()}`;
        this.dispatchEvent(new Event("change"));
    }
}

define("string-field-element", StringRequestFieldElement);
